/*
 * LvScr.h
 *
 */

#ifndef LVSCR_H_
#define LVSCR_H_

#include "LvObj.h"

namespace lvglpp
{
	struct lv_scr_t
	{
		lv_obj_t obj;
	};

	template <typename PROTYPE>
	class LvTScr : public LvTObj<PROTYPE>
	{
		using TBase = LvTObj<PROTYPE>;
		using TBase::create;

	protected:
		using TBase::_self;
		using typename TBase::TSelf;

	public:
		using TBase::raw;
		using typename TBase::RawPtr;
		inline LvTScr() noexcept requires TBase::IsHandle : LvTObj<PROTYPE>{*lv_obj_create(nullptr), TBase::AsHandle} {}
		static inline RawPtr create() noexcept { return RawPtr(lv_obj_create(nullptr)); }

		inline TSelf &load() noexcept { return lv_scr_load(raw()), _self(); }

		/**
		 * Switch screen with animation
		 * @param anim_type type of the animation from `lv_scr_load_anim_t`. E.g.  `LV_SCR_LOAD_ANIM_MOVE_LEFT`
		 * @param time time of the animation
		 * @param delay delay before the transition
		 * @param auto_del true: automatically delete the old screen
		 */
		TSelf &loadAnim(lv_scr_load_anim_t anim_type, uint32_t time, uint32_t delay, bool auto_del) noexcept { return lv_scr_load_anim(raw(), anim_type, time, delay, auto_del), _self(); }

	public:
		/**
		 * Get the active screen of the default display
		 * @return pointer to the active screen
		 */
		static inline RawPtr act(void) noexcept { return RawPtr{lv_scr_act()}; }

		/**
		 * Get the top layer  of the default display
		 * @return pointer to the top layer
		 */
		static inline RawPtr layerTop(void) noexcept { return RawPtr{lv_layer_top()}; }

		/**
		 * Get the active screen of the default display
		 * @return  pointer to the sys layer
		 */
		static inline RawPtr layerSys(void) noexcept { return RawPtr{lv_layer_sys()}; }
	};

	template <>
	struct LvProtypeTraits<lv_scr_t>
	{
		using TWrapped = LvTScr<lv_scr_t>;
		static constexpr auto &obj_class = lv_obj_class;
		static constexpr auto create = lv_obj_create;
	};

	using LvScr = LvTScr<lv_scr_t &&>;
	using LvScrPtr = LvScr::RawPtr;

} /* namespace lvglpp */

#endif /* LVSCR_H_ */
